<template>
	<view class="select-picker">
		<view :class="['select-input', `select-input--border-${borderModel}`, { 'select-input--disabled': disabled }]" @click="handleClick">
			<slot :placeholder="placeholder" :row="row">
				<view class="input">
					{{ row.label != null ? row.label : props.placeholder }}
				</view>
			</slot>
		</view>
		<v-picker-list
			v-model:value="showPicker"
			:list="options"
			:title="title"
			@confirm="handleConfirm"
			@select="handleSelect"
			:scroll-height="scrollHeight"
			:selected="value"
		></v-picker-list>
	</view>
</template>

<script setup lang="ts">
import { ref, watch, onMounted, reactive, inject, computed } from 'vue';

interface OptionsList {
	label: String;
	value: String | Number;
}
/**
 * v-select-picker 下拉框
 * value                            双向绑定
 * placeholder                        提示语
 * title                            标题
 * options                            选择值
 * initializeCustomizeFunction        自定义初始函数
 * borderModel 边框模式         	默认:all    		可选值:all普通边框 nont无边框模式 bottom底部边框模式 top上边框模式 left左边框模式 right右边框模式 ends左右两端边框模式 up-down上下边框模式
 * disabled 是否禁用           	默认:false   	可选值:true禁用 false不禁用
 * 相关事件:confirm、select
 */
const props = defineProps({
	value: {
		type: [String, Number],
		required: true
	},
	placeholder: {
		type: String,
		default: null
	},
	title: {
		type: String,
		required: true
	},
	options: {
		type: Array as () => OptionsList[],
		required: true
	},
	initializeCustomizeFunction: {
		type: Function,
		default: () => {
			return () => {};
		}
	},
	borderModel: {
		type: String,
		default: 'all',
		validator: (value: any) => {
			return ['all', 'none', 'bottom', 'top', 'left', 'right', 'ends', 'up-down'].includes(value);
		}
	},
	disabled: {
		type: Boolean,
		default: false
	},
	scrollHeight: {
		type: Number,
		default: 400
	},
	backgroundColor: {
		type: String,
		default: null
	}
});

let showPicker = ref(false);

let row = reactive({
	label: null,
	value: null
});

const emit = defineEmits(['update:value', 'confirm', 'select']);
const config = inject<any>('config');

const computedBackgroundColor = computed(() => {
	if (props.backgroundColor) {
		return props.backgroundColor;
	}
	if (config && config.backgroundColor && config.backgroundColor.reversal) {
		return config.backgroundColor.reversal;
	}
	return '#ffffff';
});

onMounted(async () => {
	await props.initializeCustomizeFunction(props.value);
	matchingData(props.value);
});

watch(
	() => props.value,
	(newValue: any) => {
		matchingData(newValue);
	}
);

watch(
	() => props.options,
	(newValue: any) => {
		matchingData(props.value);
	}
);

function matchingData(value: any) {
	const matchedItem = props.options.find((item) => item.value === value);
	if (matchedItem != undefined) {
		Object.assign(row, matchedItem);
	}
}

function handleClick() {
	if (!props.disabled) {
		showPicker.value = true;
	}
}

function handleConfirm(selected: any) {
	Object.assign(row, selected);
	emit('update:value', row.value);
	emit('confirm', row.value, row);
	showPicker.value = false;
}
function handleSelect(selected: any) {
	emit('select', selected);
}
</script>

<style lang="scss" scoped>
.select-input {
	width: 100%;
	height: 72rpx;
	line-height: 72rpx;
	background-color: v-bind('computedBackgroundColor');
	border-radius: 10rpx;
	box-sizing: border-box;

	&--border-all {
		border: 1rpx solid v-bind('config.border.color');
	}

	&--border-none {
		border: none;
	}

	&--border-bottom {
		border-bottom: 1rpx solid v-bind('config.border.color');
	}

	&--border-top {
		border-top: 1rpx solid v-bind('config.border.color');
	}

	&--border-left {
		border-left: 1rpx solid v-bind('config.border.color');
	}

	&--border-right {
		border-right: 1rpx solid v-bind('config.border.color');
	}

	&--border-ends {
		border-left: 1rpx solid v-bind('config.border.color');
		border-right: 1rpx solid v-bind('config.border.color');
	}

	&--border-up-down {
		border-top: 1rpx solid v-bind('config.border.color');
		border-bottom: 1rpx solid v-bind('config.border.color');
	}

	&--disabled {
		background-color: v-bind('config.backgroundColor.disabled');
		color: v-bind('config.fontColor.text');
		opacity: v-bind('config.opacity.disabled');
		cursor: not-allowed;
	}

	.input {
		margin-left: 2%;
		font-size: v-bind('config.fontSize.mediumText');
	}
}
</style>
